package indi.kider.server.woniubus.service;

import com.alibaba.fastjson.JSON;
import indi.kider.common.constant.*;
import indi.kider.common.model.apabus.Bus;
import indi.kider.common.model.apabus.Relet;
import indi.kider.common.model.apabus.Rent;
import indi.kider.common.model.apartment.Community;
import indi.kider.common.model.apartment.Houses;
import indi.kider.common.model.employee.Tenant;
import indi.kider.common.model.query;
import indi.kider.common.model.woniubus.DevSensetimeUpload;
import indi.kider.common.model.woniubus.TenantUpdateVo;
import indi.kider.common.model.woniubus.TenantVo;
import indi.kider.server.apabus.mapper.ReletMapper;
import indi.kider.server.apabus.mapper.RentMapper;
import indi.kider.server.apartment.mapper.CommunityMapper;
import indi.kider.server.apartment.mapper.HouseMapper;
import indi.kider.server.apartment.mapper.HousesMapper;
import indi.kider.server.employee.mapper.DevSensetimeUploadMapper;
import indi.kider.server.employee.mapper.TenantMapper;
import indi.kider.server.woniubus.service.related.BillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pers.vankid.common.model.base.CommonResponse;
import pers.vankid.common.model.base.CoreException;
import pers.vankid.common.utils.page.PageRequest;
import pers.vankid.common.utils.page.PageUtil;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.*;

@SuppressWarnings("ALL")
@Service
public class WoniuBusServiceImpl implements WoniuBusService {

    @Autowired
    private HousesMapper housesMapper;
    @Autowired
    private RentMapper rentMapper;
    @Autowired
    private ReletMapper reletMapper;
    @Autowired
    private CommunityMapper communityMapper;
    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private HouseMapper houseMapper;
    @Autowired
    private HouseService houseService;
    @Autowired
    private DevSensetimeUploadMapper devSensetimeUploadMapper;
    /**
     * 承租人租房
     * @param tenantVo
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    public CommonResponse rentHouse(TenantVo tenantVo)throws Exception{
        if (tenantVo.getRentDate() == null || tenantVo.getExpireDate() == null)
            throw new CoreException("必须指定入住时间！");
        Long houseId = tenantVo.getHouseId();
        Houses houses = housesMapper.selectByPrimaryKey(houseId);
        // 验证手机号|身份证是否被使用
        checkPhoneOrCardIdIsUse(tenantVo);
        //出租类型
        int comType =  houses.getComType();
        Tenant tenant = null;
        switch (comType){
            case  1://合租--暂不做
                throw new Exception("合租还在建设中---");
            case  2://群租
                // 验证房间是否超员
                checkHouseFull(tenantVo,houses);
                //查询用户是否已存在(根据身份证判断、),已存在则更新
                tenant = checkUseAddOrUpdate(tenantVo);
                //保存出租关系
                saveRent(tenantVo,houses,tenant.getId(),tenantVo.getOpInId());
                /*修改房屋状态*/
                houses.setState(HouseStateCons.RENTED); //1,空置 2,已租 3，配置中
                houses.setReleaseState(HouseReserveCons.NO_RESRVE); // 未发布状态
                Map<String,Object> map =  houseService.getHouseUserCntMap(houseId);
                //{ inSumCnt:3,inManCnt:1,inFemanCnt:2}
                int inSumCnt = Integer.valueOf(map.get("inSumCnt")+"");
                int inManCnt = Integer.valueOf(map.get("inManCnt")+"");
                int inFemanCnt = Integer.valueOf(map.get("inFemanCnt")+"");
//                inSumCnt ++ ;
//                if(tenant.getSex() == 1){//男
//                    inManCnt ++;
//                }else{
//                    inFemanCnt ++;
//                }
                if(inManCnt>0&&inFemanCnt>0){
                    if(tenantVo.getSex() == TenantSexTypeCons.SEX_MAN){
                        throw new CoreException("该房屋目前只能入住【女】");
                    }else{
                        throw new CoreException("该房屋目前只能入住【男】");
                    }
                }
                houses.setInSumCnt(inSumCnt);
                houses.setInManCnt(inManCnt);
                houses.setInFemanCnt(inFemanCnt);
                housesMapper.updateByPrimaryKeySelective(houses);
                break;
            default:
                throw new CoreException("暂时只支持群租入住---");
        }
        return CommonResponse.buildAddSuccessResponse("入住办理成功!",tenant);
    }

    /**
     * 验证手机号|身份证是否被使用
     */
    private void checkPhoneOrCardIdIsUse(TenantVo tenantVo)throws CoreException{
        Rent query = new Rent();
        query.setTenantTel(tenantVo.getPhone());
        query.setState(RentStateCons.VALID);
        List<Rent> rentList = rentMapper.select(query);
        if (rentList != null && !rentList.isEmpty()){
            Rent temp = rentList.get(0);
            throw new CoreException("当前手机号已被使用，使用方公寓:"+temp.getCommunity()+"-"+temp.getHouseNumb()+"-"+temp.getTenantName());
        }
        query = new Rent();
        query.setCardId(tenantVo.getCardId());
        query.setState(RentStateCons.VALID);
        rentList = rentMapper.select(query);
        if (rentList != null && !rentList.isEmpty()){
            Rent temp = rentList.get(0);
            throw new CoreException("当前身份证已被使用，使用方公寓:"+temp.getCommunity()+"-"+temp.getHouseNumb()+"-"+temp.getTenantName());
        }
    }

    /**
     * 验证房间是否超员
     * @param tenantVo
     * @throws CoreException
     */
    private void checkHouseFull(TenantVo tenantVo,Houses houses)throws CoreException{
        Rent tempRent = new Rent();
        tempRent.setHousesId(houses.getId());
        tempRent.setState(RentStateCons.VALID);
        int rentMaxCnt = rentMapper.selectCount(tempRent);//查看房间已有几人
        if(houses.getMaxCnt() <= rentMaxCnt){
            throw new CoreException("该房间已住满，已入住"+rentMaxCnt+"人!");
        }
    }

    /**
     * 查询用户是否已存在(根据身份证、电话判断、),已存在则更新
     */
    private Tenant checkUseAddOrUpdate(TenantVo tenantVo){
        Tenant tenant = JSON.parseObject(JSON.toJSONString(tenantVo), Tenant.class);
        tenant.setState(StatusCons.VALID);//有效
        tenant.setType(TenantTypeCons.TENANT);//租客
//        Tenant tempTenant = new Tenant();
//        tempTenant.setCardId(tenantVo.getCardId());
//        tempTenant.setState(2);//1:有效2：无效  3注册
//        List<Tenant> tenantList =  tenantMapper.select(tempTenant);
//        if (tenantList != null && !tenantList.isEmpty()){//已存在则更新用户信息
//            tenant.setId(tenantList.get(tenantList.size()-1).getId());
//            tenant.setPwd("123456");
//            tenantMapper.updateByPrimaryKeySelective(tenant);
//        }else{
        Tenant tempTenant = new Tenant();
        tempTenant.setCardId(tenantVo.getCardId());
        tempTenant.setState(3);//1:有效2：无效 3注册
        List<Tenant> tenantList = tenantMapper.select(tempTenant);
        if (tenantList != null && !tenantList.isEmpty()) {//已存在则更新用户信息
            tenant.setId(tenantList.get(tenantList.size() - 1).getId());
            tenant.setPwd("123456");
            tenantMapper.updateByPrimaryKeySelective(tenant);
        } else {
            tempTenant = new Tenant();
            tempTenant.setPhone(tenantVo.getPhone());
            tempTenant.setState(3);//1:有效2：无效 3注册
            tenantList = tenantMapper.select(tempTenant);
            if (tenantList != null && !tenantList.isEmpty()) {//已存在则更新用户信息
                tenant.setId(tenantList.get(tenantList.size() - 1).getId());
                tenant.setPwd("123456");
                tenantMapper.updateByPrimaryKeySelective(tenant);
            }
            tenant.setId(null);
            tenantMapper.insertSelective(tenant);
        }
//        }
        return tenant;
    }
    /**
     * 保存出租关系
     * @param tenantVo
     * @param houses
     * @param tenantId
     */
    private Rent saveRent(TenantVo tenantVo,Houses houses,Long tenantId,Long opInId){
                 /*保存rent表 出租关系*/
        Rent rent = JSON.parseObject(JSON.toJSONString(houses),Rent.class);
        Community community = communityMapper.selectByPrimaryKey(houses.getCommunityId());
        rent.setHousesId(houses.getId());
        rent.setTenantId(tenantId);
        rent.setRentDate(tenantVo.getRentDate());
        rent.setExpireDate(tenantVo.getExpireDate());
        rent.setPriceSet(tenantVo.getPriceSet());//租金取页面输入的租金
        rent.setRemark(tenantVo.getRemark());
        rent.setTenantName(tenantVo.getName());
        rent.setTenantTel(tenantVo.getPhone());
        rent.setState(RentStateCons.VALID);//1租住 3搬离
        rent.setCommunity(community.getCommunity());
        rent.setAddress(community.getAddress());
        rent.setCardId(tenantVo.getCardId());
        rent.setOpInId(opInId);
        rent.setOpInTime(new Date());
        rent.setId(null);
        rentMapper.insertSelective(rent);
        return rent;
    }

    /**
     * 续住
     * @param relet
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor=Exception.class)
    public CommonResponse reletHouse(Relet relet) throws Exception{

        Rent rent = rentMapper.selectByPrimaryKey(relet.getRentId());
        relet.setOldExpireDate(rent.getExpireDate());
        relet.setOpTime(new Date());
        reletMapper.insert(relet);

        Rent newRent = new Rent();
        newRent.setId(relet.getRentId());
        newRent.setExpireDate(relet.getNewExpireDate());
        rentMapper.updateByPrimaryKeySelective(newRent);
        return CommonResponse.buildAddSuccessResponse("续住办理成功!",null);
    }

    /**
     * 退租
     * @param rent
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor=Exception.class)
    public CommonResponse rentOutHouse(Rent rent) throws Exception{
        try{
            Rent thisRent = rentMapper.selectByPrimaryKey(rent.getId());
            //更新业务属性
            Date now = new Date();
            rent.setOpOutTime(now);
            rent.setLeaveDate(now);
            rent.setState(RentStateCons.MOVED);
            rentMapper.updateByPrimaryKeySelective(rent);
            //更新租客信息
            Tenant tenant = tenantMapper.selectByPrimaryKey(thisRent.getTenantId());
            tenant.setState(StatusCons.HISTORY);//历史==无效
            tenantMapper.updateByPrimaryKeySelective(tenant);
            //查找房屋已租客户数量
            Rent queryRent = new Rent();
            queryRent.setState(RentStateCons.VALID);
            queryRent.setHousesId(thisRent.getHousesId());

            Houses houses = new Houses();
            int cnt = rentMapper.selectCount(queryRent);//
            //更新房屋属性
            Map<String, Object> map =  houseMapper.getHouseUserCntMap(thisRent.getHousesId());
            houses.setId(thisRent.getHousesId());
            if(map != null){
                BigDecimal a  = (BigDecimal)map.get("inSumCnt");
                BigDecimal b  = (BigDecimal)map.get("inManCnt");
                BigDecimal c  = (BigDecimal)map.get("inFemanCnt");
                houses.setInSumCnt(a.intValue());
                houses.setInManCnt(b.intValue());
                houses.setInFemanCnt(c.intValue());
            }else{
                houses.setInSumCnt(0);
                houses.setInManCnt(0);
                houses.setInFemanCnt(0);
            }
            if(cnt == 0){//数量0 则修改房屋状态
                houses.setState(HouseStateCons.VACANCY);
            }
            housesMapper.updateByPrimaryKeySelective(houses);
        }catch (Exception e){
            throw new CoreException("退租办理失败!");
        }
        return CommonResponse.buildAddSuccessResponse("退租办理成功!",null);
    }

    /**
     * 查询租列表
     * @param request
     * @return
     */
    @Override
    public List<Map> getTenantListByHouseId(PageRequest<Rent> request) {
        PageUtil.start(request);
        request.getQuery().setState(RentStateCons.VALID);//1租住 3搬离
        return tenantMapper.getTenantListByHouseId(request.getQuery());
    }

    /**
     * 根据房间ID查询租客列表【已搬离】（分页）
     * @param request
     * @return
     */
    @Override
    public List<Map> getMovedTenantListByHouseId(PageRequest<Rent> request) {
        PageUtil.start(request);
        request.getQuery().setState(RentStateCons.MOVED);//1租住 3搬离
        return tenantMapper.getTenantListByHouseId(request.getQuery());
    }
    /**
     * 查询租列表 不分页
     * @param request
     * @return
     */
    @Override
    public List<Map> getTenantListByHouseIdNoPage(Rent rent) {
        rent.setState(RentStateCons.VALID);//1租住 3搬离
        return tenantMapper.getTenantListByHouseId(rent);
    }


    /**
     * 修改用户性别
     * @param tenantUpdateVo
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor=Exception.class)
    public CommonResponse modifyTenantSex(TenantUpdateVo tenantUpdateVo)throws Exception{
        Tenant tenant = new Tenant();
        tenant.setId(tenantUpdateVo.getId());
        tenant.setSex(tenantUpdateVo.getSex());
        tenantMapper.updateByPrimaryKeySelective(tenant);
        Long rentId = tenantUpdateVo.getRentId();
        if(rentId!=null && rentId > 0L){
            Rent rent = rentMapper.selectByPrimaryKey(rentId);
            //统计并保存房间男女个数
            houseService.getHouseUserCntMap(rent.getHousesId());
        }
        return CommonResponse.buildUpdateSuccessResponse("修改用户性别成功!",null);
    }

    /**
     * 修改用户信息
     * @param tenantUpdateVo
     * @return
     * @throws Exception
     */
    public CommonResponse modifyTenant(TenantUpdateVo tenantUpdateVo)throws Exception{
        Tenant tenant = JSON.parseObject(JSON.toJSONString(tenantUpdateVo),Tenant.class);
        tenantMapper.updateByPrimaryKeySelective(tenant);
        Long rentId = tenantUpdateVo.getRentId();
        if(rentId!=null && rentId > 0L){
            Rent rent = new Rent();
            rent.setId(rentId);
            rent.setTenantName(tenant.getName());
            rent.setTenantTel(tenant.getPhone());
            rent.setCardId(tenantUpdateVo.getCardId());
            rentMapper.updateByPrimaryKeySelective(rent);
        }else{
            Rent rent = new Rent();
            rent.setTenantId(tenant.getId());
            rent.setState(1);
            List<Rent> rents =rentMapper.select(rent);
            if(rents!=null&&rents.size()==1){
                Rent updateRent = rents.get(0);
                updateRent.setTenantName(tenant.getName());
                updateRent.setTenantTel(tenant.getPhone());
                updateRent.setCardId(tenantUpdateVo.getCardId());
                rentMapper.updateByPrimaryKeySelective(updateRent);
            }

        }
        return CommonResponse.buildUpdateSuccessResponse("修改用户信息成功!",null);
    }

    /**
     * 根据身份证查租客信息
     * @param cardId
     * @return
     * @throws Exception
     */
    public Tenant getTenantByCardId(String cardId)throws Exception{
        //查看一体机中的信息
        DevSensetimeUpload tempQuery = new DevSensetimeUpload();
        tempQuery.setId_number(cardId);
        tempQuery.setState(1);//有效
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DATE, -180);
        Example example = new Example(DevSensetimeUpload.class);
        example.createCriteria().andEqualTo("id_number",cardId).andGreaterThanOrEqualTo("create_date",cal.getTime());
        List<DevSensetimeUpload> devSensetimeUploads =  devSensetimeUploadMapper.selectByExample(example);
        if(devSensetimeUploads!=null&&devSensetimeUploads.size()>0){
            DevSensetimeUpload devSensetimeUpload = devSensetimeUploads.get(devSensetimeUploads.size()-1);
            Tenant ret = new Tenant();
            ret.setCardId(devSensetimeUpload.getId_number());
            ret.setName(devSensetimeUpload.getName());
            ret.setIdImage(devSensetimeUpload.getId_image());
            ret.setFaceImage(devSensetimeUpload.getFace_image());
            return ret;
        }

        Rent query = new Rent();
        query.setCardId(cardId);
        query.setState(RentStateCons.VALID);
        List<Rent> rentList = rentMapper.select(query);
        if (rentList != null && !rentList.isEmpty()){
            Rent temp = rentList.get(0);
            throw new CoreException("当前身份证已被使用，使用方公寓:"+temp.getCommunity()+"-"+temp.getHouseNumb()+"-"+temp.getTenantName());
        }
        Tenant tenQuery = new Tenant();
        tenQuery.setCardId(cardId);
        tenQuery.setState(StatusCons.HISTORY);//1:有效2：无效
        List<Tenant> list = tenantMapper.select(tenQuery);
        Tenant ret = new Tenant();
        if (list != null && !list.isEmpty()){
            ret = list.get(0);
        }
        return ret;
    }


    /**
     * 根据身份证查租客信息
     * @param cardId
     * @return
     * @throws Exception
     */
    public Tenant getDevTenantByCardId(String cardId)throws Exception{
        //查看一体机中的信息
        DevSensetimeUpload tempQuery = new DevSensetimeUpload();
        tempQuery.setId_number(cardId);
//        tempQuery.setState(1);//有效
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DATE, -180);
        Example example = new Example(DevSensetimeUpload.class);
        example.createCriteria().andEqualTo("id_number",cardId).andGreaterThanOrEqualTo("create_date",cal.getTime());
        List<DevSensetimeUpload> devSensetimeUploads =  devSensetimeUploadMapper.selectByExample(example);
        if(devSensetimeUploads!=null&&devSensetimeUploads.size()>0){
            DevSensetimeUpload devSensetimeUpload = devSensetimeUploads.get(devSensetimeUploads.size()-1);
            Tenant ret = new Tenant();
            ret.setCardId(devSensetimeUpload.getId_number());
            ret.setName(devSensetimeUpload.getName());
            ret.setIdImage(devSensetimeUpload.getId_image());
            ret.setFaceImage(devSensetimeUpload.getFace_image());
            return ret;
        }else{
            throw  new CoreException("近6个月内没有在一体机中查询到资料");
        }
    }
    /**
     * 修改发布状态
     * @param houses
     * @return
     */
    public CommonResponse updateHouseRelease(Houses houses) {
        housesMapper.updateByPrimaryKeySelective(houses);
        return CommonResponse.buildUpdateSuccessResponse("保存成功!",null);
    }
}
